package com.hzins.scher.jobholder;

import org.apache.commons.lang3.reflect.MethodUtils;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import com.google.common.base.Preconditions;
import com.hzins.scher.core.JobHolder;

@Component
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class ScherJobHolder implements JobHolder, ApplicationContextAware {

	private static ApplicationContext applicationContext;

	public void execute(JobExecutionContext context) throws JobExecutionException {
		JobDataMap dataMap = context.getMergedJobDataMap();
		String targetBeanName = (String) dataMap.remove("_targetBeanName");
		String targetMethodName = (String) dataMap.remove("_targetMethodName");
		Preconditions.checkArgument(
				(targetBeanName != null && targetMethodName != null),
				"targetBeanName or targetMethodName can not be null.");
		Object taregetObject = applicationContext.getBean(targetBeanName);
		Preconditions.checkArgument((taregetObject != null),"taregetObject can not be null.");
		try {
			if (!dataMap.isEmpty()) {
				MethodUtils.invokeMethod(taregetObject, targetMethodName,
						new Object[] { dataMap.getWrappedMap() });
			} else {
				MethodUtils.invokeMethod(taregetObject, targetMethodName, new Object[0]);
			}
		} catch (NoSuchMethodException | IllegalAccessException
				| java.lang.reflect.InvocationTargetException e) {
			throw new JobExecutionException(e);
		}
	}

	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		ScherJobHolder.applicationContext = applicationContext;
	}
}
